#include "UP_test.h"
#include "gd32f4xx.h"
#include "systick.h"
#include <stdio.h>
#include <stdlib.h>

#include "UP_GPIO.h"
#include "UP_PWM.h"
#include "UP_EXTI.h"
#include "UP_config.h"
#include "UP_USART.h"

int breathing = 1;

#define TM1CH0 TIMER1_CH0_PA5_AF1

void pwm_breathing_lamp()
{

	static int8_t direct = 1;
	static uint16_t value = 0;

	value += (300 * direct);

	if (value > 10000 || value <= 0)
	{
		direct *= -1;
	}

	PWM_update(TM1CH0, value);

	delay_1ms(20);
}

void PWM_test(void)
{
	systick_config();

	nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); // 优先级分组

	// 初始化结构体 UP_Timer timer = {RCU_TIMER1, TIMER1, TIMER_CH_0, RCU_GPIOA, GPIOA, GPIO_PIN_5, GPIO_AF_1}
	// 1000Hz = 1kHz = 1ms
	PWM_init(TM1CH0, 1000, 5000);
	PWM_update(TM1CH0, 0);

	delay_1ms(1000);
	while (1)
	{
		pwm_breathing_lamp();
		// PWM_init(TM1CH0, 0, 50);
		// delay_1ms(500);
		// PWM_update(TM1CH0, 500);
		// delay_1ms(500);
		// PWM_update(TM1CH0, 5000);
		// delay_1ms(500);
		// PWM_update(TM1CH0, 10000);
		// delay_1ms(500);
		
		// PWM_init(TM1CH0, 100, 500);
		// delay_1ms(500);
		// PWM_update(TM1CH0, 500);
		// delay_1ms(500);
		// PWM_update(TM1CH0, 5000);
		// delay_1ms(500);
		// PWM_update(TM1CH0, 10000);
		// delay_1ms(500);
	}
}


// 初始化一个5行8列的二维数组，用于存储float类型的频率值
float frequency[6][8] = {
	{0, 65.406, 73.416, 82.407, 87.307, 98.000, 110.00, 123.47},
	{0, 130.81, 146.83, 164.81, 174.61, 196.00, 220.00, 246.94},
	{0, 261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88},
	{0, 523.25, 587.33, 659.25, 698.46, 783.99, 880.00, 987.77},
	{0, 1046.50, 1174.66, 1318.51, 1396.91, 1567.98, 1760.00, 1975.53},
	{0, 2093.00, 2349.32, 2637.02, 2793.83, 3135.96, 3520.00, 3951.07}
};

void PWM_test_music(void)
{
	systick_config();

    USART_init(
        USART0,         // USART USARTx(x=0,1,2,5) / UARTx(x=3,4,6,7)
        115200U,        // 波特率
        USART_WL_8BIT,  // 数据位
        USART_STB_1BIT, // 停止位
        USART_PM_NONE   // 校验位
    );

	nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); // 优先级分组

	/**
	 * @brief
	  
	 	 notes 音符表
	  		00 代表不发音，正常持续 1/4 拍
	 		-1 代表延续之前的音符，正常持续 1/4 拍
			-2 代表接下来2个音为连音	
			-3 代表接下来3个音为连音		
		durations 延时表
			01 代表 1/4 拍
			02 代表 1/2 拍
			04 代表 1 拍
	 * 
	 */
	// 初始化 kiss the rain 的音符数组
	// int notes[] = {
	// 	00, 00, 00, 00, 45, 51, 52, 52, 53, 53, -1, 00, 51, 52, 53, 52, 55, 55, -1, 00, 55, 56, 57,
	// 	57, 61, 61, 62, -3, 63, 62, 61, 57, -1, 00, 61, 57, 55, 55, 56, 56, -1, 00, 55, 54,
	// };
	// uint8_t durations[] = {
	// 	04, 04, 04, 01, 01, 01, 01, 02, 02, 04, 04, 01, 01, 01, 01, 02, 02, 04, 04, 01, 01, 01, 01,
	// 	02, 02, 04, 02, 00, 02, 02, 02, 04, 04, 02, 02, 02, 02, 02, 02, 04, 04, 02, 01, 01,
	// };
	
	// 初始化 哆啦A梦 的音符数组http://dongyinlv.com/e/qupu/jianpu/10312.html
	int notes[] = {
		45,51,51,53,56,53,55,	55,56,55,53,54,53,52, 		46,52,52,54,57,57,56,55,
		54,54,53,46,47,51, 	  	52,-1,-1,-1,				45,51,51,53,56,53,55,
		55,56,55,53,54,53,52, 	46,52,52,54,57,57,56,55, 	54,54,53,52,47,51,
		51,-1,-1,-1,			56,56,55,54,56,55,			52,53,54,52,55,-1,
		56,55,54,-1,			52,57,56,55,56,55,54,		00,55,56,53,52,				
		51,-1,-1,-1,
		
	};
	uint8_t durations[] = {
		03,01,03,01,03,01,04, 	03,01,03,01,03,01,04, 		03,01,03,01,03,01,03,01,
		04,03,01,02,04,02,    	04,04,04,04,				03,01,03,01,03,01,04,
		03,01,03,01,03,01,04, 	03,01,03,01,03,01,03,01,	03,01,03,01,04,04,
		04,04,04,04,			04,03,01,02,02,04,			03,01,03,01,04,04,
		04,04,04,04,			04,03,01,03,01,02,02,		04,03,01,06,02,
		04,04,04,04,
	};

	// 200ms 每个音节的时长	
		// 50ms为一个四分音符
		// 100ms为一个二分音符
		// 200ms为一个全音符
	int delay_time = 300; 

	// 计算数组长度
	int notes_length = sizeof(notes) / sizeof(notes[0]);

	PWM_init(TM1CH0, 1000, 0);
	while (1)
	{
		delay_1ms(2000);
		int counter = 0;
		// 遍历数组
		for (int i = 0; i < notes_length; i++)
		{
			int note = notes[i];
			if (note > 0)
			{
				int level = note / 10 - 2;
				int index = note % 10;
				PWM_init(TM1CH0, (int)frequency[level][index], 50);
				// PWM_init(TM1CH0, 1000, 100);
				printf("level = %d index = %d freq = %d\n", level, index, (int)frequency[level][index]);
			}
			else if (note < 0)
			{
				counter = abs(note);
				// 连续 abs(notes[i]) 个接下来音符的时长
			}
			else
			{
				// -1时，延时上一个音
			}
			delay_1ms(durations[i] * delay_time / 4);

			// 延时结束后，如果counter大于0，则继续播放上一个音符
			if (counter > 0)
			{
				counter--;
			}
			else
			{
				PWM_update(TM1CH0, 0);
			}
			// 每个音符之间的间隔
			delay_1ms(delay_time / 4);
		}
	}
}


#define LED PD7
void PWM_test_motor(void)
{
    systick_config();
    GPIO_Init(LED, 0);

    // 设置中断优先级组 - 需要misc模块支持
    // 2位用于抢占优先级，2位用于响应优先级
    nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
    // 初始化，需要exti模块支持
    // EXTI_init(PG9);
    EXTI_init(PA0);

	// 1kHz -> 1ms
	PWM_init(TIMER1_CH2_PA2_AF1, 1000, 0);

    while (1) {
    }
}
int count = 0;
// void EX9_isr()

#if TEST_TYPE == TEST_PWM
void EX0_isr()
{
    if (GPIO_Get(PA0)) {
        /* 按键按下 */
        GPIO_Set(LED, 1);

		count++;
		printf("count = %d pwm = %d\n", count, count * 1000);
		if(count > 10){
			// 按键释放
			GPIO_Set(LED, 0);
			count = 0;
		}
		PWM_update(TIMER1_CH2_PA2_AF1, count * 1000);
    }
}
#endif
